home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Mark Pilgrim / Pentominoes 1.4.1 / source / Pentominoes ƒ / Pent code / pent load-save.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-30  |  8.9 KB  |  405 lines  |  [TEXT/KAHL]

  1. /**********************************************************************\
  2.  
  3. File:        pent load-save.c
  4.  
  5. Purpose:    This module handles actually loading and saving games
  6.             and solutions.
  7.  
  8.  
  9. Pentominoes - a 2-D geometry board game
  10. Copyright (C) 1993 Mark Pilgrim
  11.  
  12. This program is free software; you can redistribute it and/or modify
  13. it under the terms of the GNU General Public License as published by
  14. the Free Software Foundation; either version 2 of the License, or
  15. (at your option) any later version.
  16.  
  17. This program is distributed in the hope that it will be useful,
  18. but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20. GNU General Public License for more details.
  21.  
  22. You should have received a copy of the GNU General Public License
  23. along with this program in a file named "GNU General Public License".
  24. If not, write to the Free Software Foundation, 675 Mass Ave,
  25. Cambridge, MA 02139, USA.
  26.  
  27. \**********************************************************************/
  28.  
  29. #include "Script.h"
  30. #include "pent load-save.h"
  31. #include "pent.h"
  32. #include "pent meat.h"
  33. #include "pent files.h"
  34. #include "pent setup.h"
  35. #include "msg graphics.h"
  36. #include "msg menus.h"
  37. #include "msg dialogs.h"
  38. #include "msg sounds.h"
  39. #include "msg environment.h"
  40. #include "msg prefs.h"
  41.  
  42. FSSpec            gameFile;
  43. FSSpec            solutionFile;
  44. Boolean            deleteTheThing;
  45.  
  46. void LoadSaveDispatch(Boolean isLoad, Boolean isRealGame, Boolean useOldGame)
  47. {
  48.     if (isLoad)
  49.     {
  50.         if (isRealGame)
  51.         {
  52.             if (GetSourceFile(&gameFile, !isRealGame, useOldGame))
  53.                 GetSavedGame(&gameFile);
  54.         }
  55.         else
  56.         {
  57.             if (GetSourceFile(&solutionFile, !isRealGame, useOldGame))
  58.                 GetSolution(&solutionFile);
  59.         }
  60.     }
  61.     else
  62.     {
  63.         if (isRealGame)
  64.         {
  65.             useOldGame=useOldGame&&(gameFile.name[0]!=0x00);
  66.             if (useOldGame ? TRUE : GetDestFile(&gameFile, &deleteTheThing, isRealGame))
  67.                 SaveGame(gameFile);
  68.         }
  69.         else
  70.         {
  71.             if (GetDestFile(&solutionFile, &deleteTheThing, isRealGame))
  72.                 SaveSolution(solutionFile);
  73.         }
  74.     }
  75. }
  76.  
  77. void SaveGame(FSSpec gameFile)
  78. {
  79.     int                i,j;
  80.     int                buffer[192];
  81.     int                thisFile;
  82.     long            count;
  83.     int                iter;
  84.     OSErr            theError;
  85.     
  86.     for (i=0; i<8; i++)
  87.         for (j=0; j<20; j++)
  88.             buffer[i*20+j]=Board[i][j];
  89.     for (i=0; i<12; i++)
  90.         buffer[160+i]=PiecesPlayed[i];
  91.     buffer[172]=gNumRows;
  92.     buffer[173]=gNumCols;
  93.     buffer[174]=gNumPlayed;
  94.     buffer[175]=gWindowWidth;
  95.     buffer[176]=gWindowHeight;
  96.     buffer[177]=gWhichBoard;
  97.     for (i=0; i<12; i++)
  98.         buffer[178+i]=(int)(PieceUsed[i]);
  99.     buffer[190]=0;
  100.     buffer[191]=0;
  101.     for (i=0; i<191; i++)
  102.         buffer[191]+=buffer[i];
  103.  
  104.     if (deleteTheThing)
  105.     {
  106.         if (gHasFSSpecs)
  107.             FSpDelete(&gameFile);
  108.         else
  109.             HDelete(gameFile.vRefNum, gameFile.parID, gameFile.name);
  110.     }
  111.     FlushVol(0L, gameFile.vRefNum);
  112.     
  113.     if (gHasFSSpecs)
  114.         theError=FSpCreate(&gameFile, 'PNT5', 'PBrd', smSystemScript);
  115.     else
  116.         theError=HCreate(gameFile.vRefNum, gameFile.parID,
  117.                         gameFile.name, 'PNT5', 'PBrd');
  118.     FlushVol(0L, gameFile.vRefNum);
  119.     
  120.     if (theError==noErr)
  121.     {
  122.         if (gHasFSSpecs)
  123.             theError=FSpOpenDF(&gameFile, fsRdWrPerm, &thisFile);
  124.         else
  125.             theError=HOpen(gameFile.vRefNum, gameFile.parID,
  126.                             gameFile.name, fsRdWrPerm, &thisFile);
  127.     }
  128.     if (theError==noErr)
  129.     {
  130.         count=384L;
  131.         SetEOF(thisFile, 384L);
  132.         SetFPos(thisFile, 1, 0L);
  133.         theError=FSWrite(thisFile, &count, buffer);
  134.         FSClose(thisFile);
  135.         FlushVol(0L, gameFile.vRefNum);
  136.     }
  137.     if (theError!=noErr)
  138.     {
  139.         if (gHasFSSpecs)
  140.             FSpDelete(&gameFile);
  141.         else
  142.             HDelete(gameFile.vRefNum, gameFile.parID, gameFile.name);
  143.         ParamText("\pSorry, an error occurred trying to write the game to disk.","","","");
  144.         PositionDialog('ALRT', generalAlert);
  145.         StopAlert(generalAlert,0L);
  146.     }
  147.     else
  148.         deleteTheThing=TRUE;
  149. }
  150.  
  151. void SaveSolution(FSSpec gameFile)
  152. {
  153.     char            solution[161];
  154.     OSErr            theError;
  155.     int                thisFile;
  156.     long            count;
  157.     int                iter;
  158.     int                i,j;
  159.  
  160.     iter=1;
  161.     solution[0]=gWhichBoard+0x20;
  162.     for (i=0; i<gNumRows; i++)
  163.         for (j=0; j<gNumCols; j++)
  164.             solution[iter++]=SolutionLetters[Board[i][j]+1];
  165.     
  166.     
  167.     if (deleteTheThing)
  168.     {
  169.         if (gHasFSSpecs)
  170.             FSpDelete(&gameFile);
  171.         else
  172.             HDelete(gameFile.vRefNum, gameFile.parID, gameFile.name);
  173.     }
  174.     FlushVol(0L, gameFile.vRefNum);
  175.     
  176.     if (gHasFSSpecs)
  177.         theError=FSpCreate(&gameFile, 'ttxt', 'TEXT', smSystemScript);
  178.     else
  179.         theError=HCreate(gameFile.vRefNum, gameFile.parID,
  180.                         gameFile.name, 'ttxt', 'TEXT');
  181.     FlushVol(0L, gameFile.vRefNum);
  182.     
  183.     if (theError==noErr)
  184.     {
  185.         if (gHasFSSpecs)
  186.             theError=FSpOpenDF(&gameFile, fsRdWrPerm, &thisFile);
  187.         else
  188.             theError=HOpen(gameFile.vRefNum, gameFile.parID,
  189.                             gameFile.name, fsRdWrPerm, &thisFile);
  190.     }
  191.     
  192.     if (theError==noErr)
  193.     {
  194.         count=iter;
  195.         SetEOF(thisFile, count);
  196.         SetFPos(thisFile, 1, 0L);
  197.         theError=FSWrite(thisFile, &count, solution);
  198.         FSClose(thisFile);
  199.         FlushVol(0L, gameFile.vRefNum);
  200.     }
  201.     if (theError!=noErr)
  202.     {
  203.         if (gHasFSSpecs)
  204.             FSpDelete(&gameFile);
  205.         else
  206.             HDelete(gameFile.vRefNum, gameFile.parID, gameFile.name);
  207.         ParamText("\pSorry, an error occurred trying to write the solution to disk.","","","");
  208.         PositionDialog('ALRT', generalAlert);
  209.         StopAlert(generalAlert,0L);
  210.     }
  211.     else
  212.         deleteTheThing=TRUE;
  213. }
  214.  
  215. void GetSavedGame(FSSpec *gameFile)
  216. {
  217.     int                thisFile;
  218.     int                checksum,checkFile;
  219.     long            count;
  220.     int                i,j;
  221.     int                tempWhich;
  222.     Boolean            tempInteractive;
  223.     int                buffer[192];
  224.     OSErr            theError;
  225.  
  226.     if (gHasFSSpecs)
  227.         theError=FSpOpenDF(gameFile, fsRdPerm, &thisFile);
  228.     else
  229.         theError=HOpen(gameFile->vRefNum, gameFile->parID, gameFile->name, fsRdPerm, &thisFile);
  230.  
  231.     if (theError==noErr)
  232.     {
  233.         count=384L;
  234.         SetFPos(thisFile, 1, 0L);
  235.         theError=FSRead(thisFile, &count, buffer);
  236.         FSClose(thisFile);
  237.     }
  238.     else
  239.     {
  240.         ParamText("\pSorry, an error occurred while trying to read the game from disk.","","","");
  241.         PositionDialog('ALRT', generalAlert);
  242.         StopAlert(generalAlert,0L);
  243.         return;
  244.     }
  245.     
  246.     if (theError==noErr)
  247.     {                
  248.         for (i=0; i<8; i++)
  249.             for (j=0; j<20; j++)
  250.                 Board[i][j]=buffer[i*20+j];
  251.         for (i=0; i<12; i++)
  252.             PiecesPlayed[i]=buffer[160+i];
  253.         gNumRows=buffer[172];
  254.         gNumCols=buffer[173];
  255.         gNumPlayed=buffer[174];
  256.         gWindowWidth=buffer[175];
  257.         gWindowHeight=buffer[176];
  258.         tempWhich=buffer[177];
  259.         for (i=0; i<12; i++)
  260.             PieceUsed[i]=(Boolean)(buffer[178+i]);
  261.         tempInteractive=(Boolean)(buffer[190]);
  262.         checkFile=buffer[191];
  263.         
  264.         checksum=0;
  265.         for (i=0; i<191; i++)
  266.                 checksum+=buffer[i];
  267.  
  268.         if (checksum!=checkFile)
  269.         {
  270.             ParamText("\pSorry, this game file is damaged or has been altered.","","","");
  271.             PositionDialog('ALRT', generalAlert);
  272.             StopAlert(generalAlert, 0L);
  273.         }
  274.         else
  275.         {
  276.             gNumHilited=0;
  277.             for (i=0; i<gNumRows; i++)
  278.                 for (j=0; j<gNumCols; j++)
  279.                     if (Board[i][j]==-2)
  280.                         gNumHilited++;
  281.             deleteTheThing=TRUE;
  282.             gWhichBoard=tempWhich;
  283.             SaveThePrefs();
  284.             OpenNewGame();
  285.         }
  286.     }
  287.     else
  288.     {
  289.         ParamText("\pSorry, an error occurred while trying to read the game from disk.","","","");
  290.         PositionDialog('ALRT', generalAlert);
  291.         StopAlert(generalAlert,0L);
  292.     }
  293. }
  294.  
  295. void GetSolution(FSSpec *solutionFile)
  296. {
  297.     int                thisFile;
  298.     Boolean            badfile;
  299.     long            count;
  300.     int                i,j;
  301.     char            solution[161];
  302.     OSErr            theError;
  303.     int                iter,thisone;
  304.     int                oldBoard;
  305.     
  306.     if (gHasFSSpecs)
  307.         theError=FSpOpenDF(solutionFile, fsRdPerm, &thisFile);
  308.     else
  309.         theError=HOpen(solutionFile->vRefNum, solutionFile->parID, solutionFile->name, fsRdPerm, &thisFile);
  310.  
  311.     if (theError==noErr)
  312.     {
  313.         oldBoard=gWhichBoard;
  314.         badfile=FALSE;
  315.         count=1L;
  316.         SetFPos(thisFile, 1, 0L);
  317.         theError=FSRead(thisFile, &count, solution);
  318.     }
  319.     else
  320.     {
  321.         ParamText("\pSorry, an error occurred trying to read the solution from disk.","","","");
  322.         PositionDialog('ALRT', generalAlert);
  323.         StopAlert(generalAlert,0L);
  324.         gWhichBoard=oldBoard;
  325.         return;
  326.     }
  327.     
  328.     if (theError==noErr)
  329.     {
  330.         gWhichBoard=solution[0]-0x20;
  331.         if ((gWhichBoard<1) || (gWhichBoard>31))
  332.         {
  333.             badfile=TRUE;
  334.             theError=noErr;
  335.         }
  336.         else
  337.         {
  338.             CalculateRowsandCols();
  339.             count=(long)(gNumRows*gNumCols);
  340.             SetFPos(thisFile, 1, 1L);
  341.             theError=FSRead(thisFile, &count, &(solution[1]));
  342.         }
  343.     }
  344.     
  345.     FSClose(thisFile);
  346.     
  347.     if (theError==noErr)
  348.     {
  349.         if (!badfile)
  350.         {
  351.             iter=1;
  352.             for (i=0; i<gNumRows; i++)
  353.                 for (j=0; j<gNumCols; j++)
  354.                 {
  355.                     thisone=0;
  356.                     while ((thisone<14) && (SolutionLetters[thisone]!=solution[iter]))
  357.                         thisone++;
  358.                     badfile=(thisone==14);
  359.                     if (badfile)
  360.                     {
  361.                         j=gNumCols;
  362.                         i=gNumRows;
  363.                     }
  364.                     else
  365.                     {
  366.                         Board[i][j]=thisone-1;
  367.                         iter++;
  368.                     }
  369.                 }
  370.         }
  371.         
  372.         if (badfile)
  373.         {
  374.             ParamText("\pSorry, this file is not a solution file.","","","");
  375.             PositionDialog('ALRT', generalAlert);
  376.             StopAlert(generalAlert, 0L);
  377.             gWhichBoard=oldBoard;
  378.         }
  379.         else
  380.         {
  381.             for (i=0; i<12; i++)
  382.             {
  383.                 PiecesPlayed[i]=i;
  384.                 PieceUsed[i]=TRUE;
  385.             }
  386.             gNumPlayed=12;
  387.             gWindowWidth = (gNumCols*25) + 10;
  388.             gWindowHeight = (gNumRows*25) + 95;
  389.             gNumHilited=0;
  390.             
  391.             deleteTheThing=TRUE;
  392.             SaveThePrefs();
  393.             gameFile.name[0]=0x00;
  394.             OpenNewGame();
  395.         }
  396.     }
  397.     else
  398.     {
  399.         ParamText("\pSorry, an error occurred trying to read the solution from disk.","","","");
  400.         PositionDialog('ALRT', generalAlert);
  401.         StopAlert(generalAlert,0L);
  402.         gWhichBoard=oldBoard;
  403.     }
  404. }
  405.